﻿
/**************************************************************
*作者：jjpeng
*邮箱：ling121211@gmail.com
*时间：2011-10-30 23:33:49
*说明：类型转换
**************************************************************/

using System;
using System.Collections.Generic;
using System.Text;

using System.Reflection;

namespace PCC.Framework.Utils
{
    /// <summary>
    /// 用于数据类型转换
    /// </summary>
    public class ParseHelper
    {
        #region 公开方法
        /// <summary>
        /// 将输入值转换为类型T
        /// </summary>
        /// <typeparam name="T">返回的类型参数</typeparam>
        /// <param name="obj">待转换的参数</param>
        /// <returns></returns>
        public static T Parse<T>(object obj) 
        {
            return Parse<T>(obj, GetDefaultValue<T>());
        }

        /// <summary>
        /// 将输入值转换为类型T，若输入为空，则返回 defaultValue
        /// </summary>
        /// <typeparam name="T">返回的类型参数</typeparam>
        /// <param name="obj">待转换的参数</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static T Parse<T>(object obj, T defaultValue)
        {
            T value;
            if (obj == null || obj == DBNull.Value || string.IsNullOrEmpty(obj.ToString()))
            {
                value = defaultValue;
            }
            else
            {
                value = (T)Convert.ChangeType(obj, typeof(T));
            }
            return value;
        }

        /// <summary>
        /// 获取类型T默认实例值
        /// 数字类型(short, ushort, int ,uint, float, double, decimal, long, ulong)
        /// String
        /// Boolean
        /// Enum
        /// DateTime
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetDefaultValue<T>()
        {
            Type t = typeof(T);
            if (IsNumType(t))
                return ParseType<T>(0, t);
            else if (IsStringType(t))
                return ParseType<T>(string.Empty, t);
            else if (IsBooleanType(t))
                return ParseType<T>(false, t);
            else if (IsDateTimeType(t))
                return ParseType<T>(new DateTime(1000, 1, 1), t);
            else
                return Activator.CreateInstance<T>();
        }
        #endregion

        #region 私有方法
        private static T ParseType<T>(object obj, Type t)
        {
            return (T)Convert.ChangeType(obj, t);
        }

        private static bool IsBooleanType(Type t)
        {
            return t.Equals(typeof(bool));
        }

        private static bool IsNumType(Type t)
        {
            return t.Equals(typeof(short)) || t.Equals(typeof(ushort)) || t.Equals(typeof(int)) || t.Equals(typeof(uint))
                || t.Equals(typeof(float)) || t.Equals(typeof(double)) || t.Equals(typeof(decimal)) || t.Equals(typeof(long)) || t.Equals(typeof(ulong));
        }

        private static bool IsStringType(Type t)
        {
            return t.Equals(typeof(string));
        }

        private static bool IsDateTimeType(Type t)
        {
            return t.Equals(typeof(DateTime));
        }
        #endregion
    }
}
